/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-09-04     SenyPC       the first version
 */
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include <dfs_fs.h>
#include "fal.h"
#include "drv_common.h"
#include "drv_sdio.h"

#define DBG_TAG "app.filesystem"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#define SD_CHECK_PIN         GET_PIN(D, 0)     //检测cd引脚

#define SPI_FLASH_NAME      BLK_DEV_NAME
#define SPI_FLASH_FORMAT    "lfs"
//#define SPI_FLASH_NAME      NOR_FLASH_DEV_NAME
//#define SPI_FLASH_FORMAT    "elm"

/* 外部SPI Flash 分区挂载 */
int filesystem_mount(void) {
    int ret = 0;
    DIR *dirp = RT_NULL;
    if(rt_device_find(SPI_FLASH_NAME) != RT_NULL)  {
        if (RT_EOK != dfs_mount(SPI_FLASH_NAME, "/", SPI_FLASH_FORMAT, 0, 0)) {
            if(RT_EOK != dfs_mkfs(SPI_FLASH_FORMAT, SPI_FLASH_NAME)) {    //加载失败，可以尝试先格式化磁盘
                LOG_E(SPI_FLASH_NAME" "SPI_FLASH_FORMAT" failed!");
                return -RT_ERROR;
            }
            //格式化之后重新加载设备
            if (RT_EOK != dfs_mount(SPI_FLASH_NAME, "/", SPI_FLASH_FORMAT, 0, 0)) {
                LOG_E(SPI_FLASH_NAME" mount to '/' failed!");
                return -RT_ERROR;
            }
        }
        dirp = opendir("/sd0");
        if(NULL== dirp) {
           ret = mkdir("/sd0",0x777);
           if(0 > ret) {
               LOG_E("dir '/sd0' create error.");
                return -RT_ERROR;
           }
        }
        LOG_I(SPI_FLASH_NAME" mount to '/'");
    }
    return RT_EOK;
}

/* 外部SPI Flash 分区卸载 */
int filesystem_unmount(void) {
    if(rt_device_find(SPI_FLASH_NAME) != RT_NULL)  {
        if (RT_EOK == dfs_unmount("/")) {
            LOG_D(SPI_FLASH_NAME"unmount ok!");
        } else {
            LOG_E(SPI_FLASH_NAME"unmount fail!");
        }
    }
    return RT_EOK;
}

static int mount_init(void)
{
    return filesystem_mount();    /* 挂载 SPI Flash 为 根目录 */
}
INIT_ENV_EXPORT(mount_init);


int mnt_sd_mount(void)    /* 外部SPI Flash 分区挂载 */
{
    rt_device_t device;
    device = rt_device_find("sd0");
    if(RT_NULL == device) {
        mmcsd_wait_cd_changed(0);
        at32_mmcsd_change();
        mmcsd_wait_cd_changed(RT_WAITING_FOREVER);
        device = rt_device_find("sd0");
    }
    if (device != RT_NULL) {
        if (RT_EOK != dfs_mount("sd0", "/sd0", "elm", 0, 0)) {
            LOG_E("sd0 mount to '/sd0' failed!");
            return -RT_ERROR;
        }
        LOG_I("sd0 mount to '/sd0'");
        return RT_EOK;
    }
    LOG_E("dev(sd0) is not found.");
    return -RT_ERROR;
}

int mnt_sd_unmount(void)
{
    rt_thread_mdelay(200);
    dfs_unmount("/sd0");

    mmcsd_wait_cd_changed(0);
    at32_mmcsd_change();
    mmcsd_wait_cd_changed(RT_WAITING_FOREVER);
    return RT_EOK;
}

static void sd_mount(void *parameter) {
    rt_uint8_t re_sd_check = 1;
    rt_thread_delay(RT_TICK_PER_SECOND);
    while (1) {
        rt_thread_mdelay(200);
        if(re_sd_check && (!rt_pin_read(SD_CHECK_PIN))) {
            if(RT_EOK == mnt_sd_mount()) {
                re_sd_check = 0;
            } else {
                re_sd_check = 0;
            }
        }
        if (!re_sd_check && rt_pin_read(SD_CHECK_PIN)) {
            mnt_sd_unmount();
            re_sd_check = 1;
            LOG_I("sd0 unmount success");
        }
    }
}

static int filesystem_init(void){
    rt_thread_t tid;
    rt_pin_mode(SD_CHECK_PIN, PIN_MODE_INPUT_PULLUP);
    tid = rt_thread_create("sd_mount",sd_mount, RT_NULL,2048, 8, 10);
    if (tid != RT_NULL){
        rt_thread_startup(tid);
    }
    else{
        LOG_E("filesystem_init failed!");
    }
    return 0;
}
INIT_APP_EXPORT(filesystem_init);



